home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i099: Graphics editor for Suns, Part03/06
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: steinmetz!sbcs!nyfca1!chan (Douglas Chan)
- Posting-number: Volume 11, Issue 99
- Archive-name: graphedit/part03
-
- [ Note the /tmp/catshar, and the way that "draw.c" is split into two
- files. Douglas did a nice packing jobs on this submission. --r$ ]
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Contents: draw.c.shar2 /tmp/catshar
-
- echo x - draw.c.shar2
- sed 's/^@//' > "draw.c.shar2" <<'@//E*O*F draw.c.shar2//'
- /* create segment for the text sample if it is not there */
- if ( !(dlist=ge_display_list(GE_CHAR_SAMPLE)) ) {
- make_new_seg(GE_CHAR_SAMPLE);
- dlist=ge_display_list(GE_CHAR_SAMPLE);
- ge_graph(GE_CHAR_SAMPLE, GE_MOVE, TEXTX, TEXTY);
- ge_graph(GE_CHAR_SAMPLE, GE_TEXT, (float)((int)text_sample), 0.);
- } /* if */
-
- /* change font of text sample and draw sample */
- dlist->attr.font=value;
- attr_changed = 1;
- ge_draw(GE_CHAR_SAMPLE);
-
- } /* do_change_font */
-
- /*****************************************************************************
-
- do_change_charsize is the notify procedure of the slider for character
- size. It will create the text sample if it is not there and update the
- size of the test sample according to the value of the slider.
-
- *****************************************************************************/
-
- do_change_charsize(item, value, event)
- Panel_item item;
- int value;
- Event *event;
- {
- struct list *dlist;
-
- /* create segment for text sample if it is not there */
- if ( !(dlist=ge_display_list(GE_CHAR_SAMPLE)) ) {
- make_new_seg(GE_CHAR_SAMPLE);
- dlist=ge_display_list(GE_CHAR_SAMPLE);
- ge_graph(GE_CHAR_SAMPLE, GE_MOVE, TEXTX, TEXTY);
- ge_graph(GE_CHAR_SAMPLE, GE_TEXT, (float)((int)text_sample), 0.);
- }
-
- /* change character size of text sample and draw sample */
- dlist->attr.charsize=value;
- attr_changed = 1;
- ge_draw(GE_CHAR_SAMPLE);
-
- } /* do_change_charsize */
-
- /*****************************************************************************
-
- do_change_linestyle is the notify procedure of the linestyle choice.
- It will create the line sample if it is not there and update the line
- style of the line sample according to the value chosen.
-
- *****************************************************************************/
-
- /* define coordinates of line sample */
- #define LINEX 80.
- #define LINEY 370.
-
- do_change_linestyle(item, value, event)
- Panel_item item;
- int value;
- Event *event;
- {
- struct list *dlist;
-
- /* create segment for line sample if it is not there */
- if ( !(dlist=ge_display_list(GE_LINE_SAMPLE)) ) {
- make_new_seg(GE_LINE_SAMPLE);
- dlist=ge_display_list(GE_LINE_SAMPLE);
- ge_graph(GE_LINE_SAMPLE, GE_MOVE, LINEX, LINEY);
- ge_graph(GE_LINE_SAMPLE, GE_LINE, LINEX+60., LINEY);
- }
-
- /* update line style of line sample and draw sample */
- dlist->attr.linestyle=value;
- attr_changed = 1;
- ge_draw(GE_LINE_SAMPLE);
-
- } /* do_change_linestyle */
-
- /*****************************************************************************
-
- do_change_linewidth is the notify procedure of the slider for line widths.
- It will create the line sample if it is not there and update the line
- width of the line sample according to the value of the slider.
-
- *****************************************************************************/
-
- do_change_linewidth(item, value, event)
- Panel_item item;
- int value;
- Event *event;
- {
- struct list *dlist;
-
- /* create segment for the line sample if necessary */
- if ( !(dlist=ge_display_list(GE_LINE_SAMPLE)) ) {
- make_new_seg(GE_LINE_SAMPLE);
- dlist=ge_display_list(GE_LINE_SAMPLE);
- ge_graph(GE_LINE_SAMPLE, GE_MOVE, LINEX, LINEY);
- ge_graph(GE_LINE_SAMPLE, GE_LINE, LINEX+60., LINEY);
- } /* if */
-
- /* update line width of line sample and draw sample */
- dlist->attr.linewidth=value;
- attr_changed = 1;
- ge_draw(GE_LINE_SAMPLE);
-
- } /* do_change_linewidth */
-
-
- /*****************************************************************************
-
- do_break is used to break a segment into segments with one primitive
- in each segment. It scans the display list of the segment looking for
- instructions such as GE_MOVE and GE_POLYGON which imply the beginning
- of a primitive and create a new segment for it.
-
- *****************************************************************************/
-
- do_break()
- {
- int segnam;
- struct list *dlist;
- struct list_item *ptr;
- struct attr attr;
- int fill;
-
- do_message("");
- /* ask for number of segment to break */
- do_usage("Select segment","","");
- if ( ! (segnam=ge_pick()) ) {
- do_usage("","","");
- do_message("No segment selected.");
- return;
- } /* if */
- do_usage("","","");
-
- /* delete segment from view surface */
- dlist = ge_display_list(segnam);
- attr = dlist->attr;
- attr.drawn = 0;
- dlist->attr.deleted=1;
- ge_draw(segnam);
-
- if ( ptr=dlist->d_list ) {
- ptr=ptr->next;
- segopen = FALSE;
- fill = 0;
-
- /* scan the display list to create the new segments */
- do {
- switch ( ptr->instr ) {
-
- /* create new segment at GE_MOVE and GE_PLOT */
- case GE_MOVE:
- case GE_PLOT:
- if ( segopen )
- ge_draw(opensegment);
- make_new_seg(0);
- curr_dlist->attr=attr;
- break;
-
- case GE_POLYGON:
- /* create new segment at GE_POLYGON */
- if ( segopen )
- ge_draw(opensegment);
- make_new_seg(0);
- curr_dlist->attr=attr;
-
- case GE_CIRCLE:
- case GE_ELLIPSE:
- /* set up the proper fill instruction for polygon, circle
- and ellipse */
- if (fill) {
- ge_graph(opensegment, GE_FILL, (float)fill, 0.);
- fill = 0;
- }
- break;
-
- /* no special action for these instructions */
- case GE_LINE:
- case GE_POLYLINE:
- case GE_TEXT:
- case GE_CONT:
- case GE_ARC:
- case GE_ARCEXT:
- break;
-
- /* save the fill instruction value, which will be used by
- the next polygon, circle or ellipse */
- case GE_FILL:
- fill = (int)ptr->x;
- break;
-
- /* save any change of attributes, which will be used as the
- initial attributes of the next created segment */
- case GE_SETCOLOR:
- attr.color=(int)ptr->x;
- break;
- case GE_SETTYPELINE:
- attr.linestyle=(int)ptr->x;
- break;
- case GE_SETLINEWIDTH:
- attr.linewidth=(int)ptr->x;
- break;
- case GE_SETFONT:
- attr.font=(int)ptr->x;
- break;
- case GE_SETCHARSIZE:
- attr.charsize=(int)ptr->x;
- break;
-
- /* check that all possible instructions are properly handled */
- default:
- fprintf(stderr,
- "Internal Error-Action for instruction %d missing.\n",
- ptr->instr);
- break;
-
- } /* switch */
-
- /* add instruction to the current segment */
- ge_graph(opensegment, ptr->instr, ptr->x, ptr->y);
- ptr=ptr->next;
-
- } while (ptr != dlist->d_list->next);
-
- } /* if */
-
- /* draw the last segment created */
- ge_draw(opensegment);
-
- /* delete the old segment */
- ge_delete_segment(segnam);
- segopen = FALSE;
-
- /* repeat if the continous option is on */
- if ( panel_get_value(cycle_cont) ) do_break();
-
- } /* do_break */
-
- /*****************************************************************************
-
- ge_newscale is used to determine the scaling factor for radius of circles
- or character size of text when a segment is joined to another segment.
-
- Input
- sx1, sy1 - x,y scale of segment to be joined
- sx2, sy2 - x,y scale of segment joining to the first segment
-
- Output
- Return the scaling factor determined.
-
- *****************************************************************************/
-
- float ge_newscale(sx1, sy1, sx2, sy2)
- float sx1, sy1, sx2, sy2;
- {
- return (sqrt((double)
- ((sx2 * sx2 + sy2 * sy2)/
- (sx1 * sx1 + sy1 * sy1))));
-
- } /* ge_newscale */
-
- /*****************************************************************************
-
- do_join is used to join a number of segments to form one segment. It will
- ask the user to pick the first segment. The display list of all the following
- segments picked will be appended to the display list of the first segment
- after any apporpiate changes. It will finish when the user do not pick any
- segment or pick the first segment.
-
- *****************************************************************************/
-
- do_join()
- {
- int segnam, firstsegment;
- struct list *dlist, *first_dlist;
- struct list_item *ptr;
- struct attr attr;
- float sina, cosa;
-
- /* ask the user to pick the first segment */
- do_message("");
- do_usage("First segment","","");
- if ( ! (firstsegment=ge_pick()) ) {
- /* abort if no segment picked */
- do_usage("","","");
- do_message("No segment selected.");
- return;
- } /* if */
-
- /* get the display list of the first segment */
- segopen = FALSE;
- first_dlist = ge_display_list(firstsegment);
- curr_dlist = first_dlist;
- attr = first_dlist->attr;
-
- /* update attr according to display list of first segment
- to obtain attributes at the end of the display list */
- if ( ptr=first_dlist->d_list ) {
- ptr=ptr->next;
- do {
-
- switch ( ptr->instr ) {
- case GE_SETCOLOR:
- attr.color = (int) ptr->x;
- break;
- case GE_SETTYPELINE:
- attr.linestyle = (int) ptr->x;
- break;
- case GE_SETLINEWIDTH:
- attr.linewidth = (int) ptr->x;
- break;
- case GE_SETFONT:
- attr.font = (int) ptr->x;
- break;
- case GE_SETCHARSIZE:
- attr.charsize = (int) ptr->x;
- break;
- default: break;
- } /* switch */
- ptr=ptr->next;
-
- } while ( ptr != first_dlist->d_list->next );
-
- } /* if */
-
- /* ask user to pick a number of segments to join */
- do_message("Select first or no segment when done.");
- do_usage("Select segment", "", "");
-
- /* join until user pick no/first segment */
- while (((segnam=ge_pick()) && (segnam != firstsegment))) {
-
- float newscale;
-
- dlist = ge_display_list(segnam);
- newscale=ge_newscale(dlist->attr.sx, dlist->attr.sy, attr.sx, attr.sy);
-
- /* change character size of new segment according to the difference
- in scale between the two segments */
- dlist->attr.charsize = (float)dlist->attr.charsize / newscale;
-
- /* change attributes of the first segment to the initial attributes
- of the joining segment */
- if ( dlist->attr.color != attr.color ) {
- ge_graph(firstsegment, GE_SETCOLOR, (float)dlist->attr.color, 0.);
- attr.color = dlist->attr.color;
- }
- if ( dlist->attr.linestyle != attr.linestyle ) {
- ge_graph(firstsegment, GE_SETTYPELINE, (float)dlist->attr.linestyle, 0.);
- attr.linestyle = dlist->attr.linestyle;
- }
- if ( dlist->attr.linewidth != attr.linewidth ) {
- ge_graph(firstsegment, GE_SETLINEWIDTH, (float)dlist->attr.linewidth, 0.);
- attr.linewidth = dlist->attr.linewidth;
- }
- if ( dlist->attr.font != attr.font ) {
- ge_graph(firstsegment, GE_SETFONT, (float)dlist->attr.font, 0.);
- attr.font = dlist->attr.font;
- }
- if ( dlist->attr.charsize != attr.charsize ) {
- ge_graph(firstsegment, GE_SETCHARSIZE, (float)dlist->attr.charsize, 0.);
- attr.charsize = dlist->attr.charsize;
- }
-
- sina = sin((double)dlist->attr.ang);
- cosa = cos((double)dlist->attr.ang);
-
- /* append the display list of the joining segment to the display list
- of the first segment */
- if ( ptr=dlist->d_list ) {
- ptr=ptr->next;
- do {
-
- float nx, ny, wx, wy;
-
- /* add item to segment */
- switch ( ptr->instr ) {
- case GE_MOVE:
- case GE_LINE:
- case GE_PLOT:
- case GE_POLYLINE:
- case GE_POLYGON:
- case GE_CONT:
- /* transform point to world coordinate */
- wx = dlist->attr.sx * cosa * ptr->x -
- dlist->attr.sy * sina * ptr->y + dlist->attr.tx;
- wy = dlist->attr.sx * sina * ptr->x +
- dlist->attr.sy * cosa * ptr->y + dlist->attr.ty;
- unxform(wx,wy,&nx,&ny);
- break;
-
- case GE_CIRCLE:
- case GE_ARCEXT:
- /* the radius has to be scaled according to the difference
- in scale */
- nx = ptr->x / newscale;
- ny = ptr->y;
- break;
-
- case GE_ELLIPSE:
- /* scale height and width of ellipse according to the
- difference in scale */
- nx = ptr->x * dlist->attr.sx / attr.sx;
- ny = ptr->y * dlist->attr.sy / attr.sy;
- break;
-
- case GE_ARC:
- /* change starting and ending angle of arc according to
- the difference in rotation */
- nx = ptr->x + dlist->attr.ang - attr.ang;
- ny = ptr->y + dlist->attr.ang - attr.ang;
- break;
-
- case GE_TEXT:
- case GE_FILL:
- /* nothing has to be changed */
- nx = ptr->x; ny = ptr->y;
- break;
-
- /* update current attribute of first segment */
- case GE_SETCOLOR:
- attr.color = (int) ptr->x;
- nx = ptr->x; ny = ptr->y;
- break;
- case GE_SETTYPELINE:
- attr.linestyle = (int) ptr->x;
- nx = ptr->x; ny = ptr->y;
- break;
- case GE_SETLINEWIDTH:
- attr.linewidth = (int) ptr->x;
- nx = ptr->x; ny = ptr->y;
- break;
- case GE_SETFONT:
- attr.font = (int) ptr->x;
- nx = ptr->x; ny = ptr->y;
- break;
- case GE_SETCHARSIZE:
- /* character size has to be scaled according to difference
- in scale */
- ptr->x /= newscale;
- attr.charsize = (int) ptr->x;
- nx = ptr->x; ny = ptr->y;
- break;
-
- /* check that all instuctions are properly handled */
- default:
- fprintf(stderr,
- "Internal Error-Action for instruction %d missing.\n",
- ptr->instr);
- break;
-
- } /* switch */
-
- /* add instruction to first segment */
- ge_graph(firstsegment, ptr->instr, nx, ny);
- ptr=ptr->next;
-
- } while ( ptr != dlist->d_list->next );
-
- } /* if */
-
- /* delete the segment */
- dlist->attr.deleted = 1;
- ge_draw(segnam);
- ge_delete_segment(segnam);
-
- /* redraw first segment */
- ge_draw(firstsegment);
-
- } /* while */
-
- do_message("");
- do_usage("","","");
-
- } /* do_join */
-
- /*****************************************************************************
-
- do_clear will ask for confirmation of the clear and delete all
- segments (except the samples) from the display list and the view
- surface upon confirmation.
-
- *****************************************************************************/
-
- do_clear()
- {
- int i, tmp;
- extern int ge_seglist;
- extern struct list ge_open[];
-
- do_message("");
- if (!(wmgr_confirm(basefd,"Press the left mouse button to confirm Clear. To cancel, press the right mouse button now."))) {
- /* clear is cancelled */
- do_message("Cancelled.");
- return;
- } /* if */
-
- /* scan the segment list to delete all segments */
- for ( i=ge_seglist; i; i=tmp ) {
-
- tmp = ge_open[i].next;
-
- /* samples are excluded */
- if ( ge_open[i].segno >= GE_MIN_SEG ) {
-
- /* remove segment from display */
- ge_open[i].attr.deleted=1;
- ge_draw(ge_open[i].segno);
-
- /* remove segment from segment list */
- ge_delete_segment(ge_open[i].segno);
-
- } /* if */
- } /* for */
- segopen=FALSE;
-
- } /* do_clear */
-
- /*****************************************************************************
-
- do_copy_segment is used to make a copy of a segment. It will ask the
- user to pick a segment, create a new segment and copy the display list of
- the old segment to the new segment, and ask the user to move the new
- segment to its proper position.
-
- *****************************************************************************/
-
- do_copy_segment()
- {
- int segnam, butnum;
- float tx0, ty0, tx, ty, x, y, wx, wy;
- struct list *dlist,*newdlist;
- struct list_item *ptr;
-
- /* ask for number of segment to copy */
- do_message("");
- do_usage("Select segment","","");
- if (segnam=ge_pick() ) {
-
- ge_locator(-1, &butnum, &wx, &wy);
-
- /* create new segment */
- make_new_seg(0);
- segopen=FALSE;
-
- /* copy display list and attributes to new segment */
- dlist = ge_display_list(segnam);
- newdlist = ge_display_list(opensegment);
- newdlist->attr = dlist->attr;
- newdlist->attr.drawn = 0;
- if ( ptr=dlist->d_list ) {
- ptr=ptr->next;
- do {
- ge_graph(opensegment, ptr->instr, ptr->x, ptr->y);
- ptr=ptr->next;
- } while ( ptr != dlist->d_list->next );
- }
-
- /* draw new segment */
- ge_draw(opensegment);
-
- /* ask to user to move the new segment */
- tx0 = newdlist->attr.tx; ty0 = newdlist->attr.ty;
- do_message("Move the new segment to its location.");
- do_usage("", "", "Done");
- do {
- float tx, ty;
-
- /* determine amount of movement */
- ge_locator(-1,&butnum, &x, &y);
- tx = x-wx;
- ty = y-wy;
- ge_align(&tx,&ty);
- dlist->attr.tx = tx0 + tx;
- dlist->attr.ty = ty0 + ty;
-
- /* redraw both segments */
- ge_redisplay(newdlist);
- ge_redisplay(dlist);
-
- } while ( butnum != 3 );
- segopen = FALSE;
- do_message("");
- }
- else {
- do_message("No segment selected.");
- }
-
- do_usage("","","");
-
- /* repeat if the continous option is on */
- if ( segnam && panel_get_value(cycle_cont) )
- do_copy_segment();
-
- } /* do_copy_segment */
-
- /*****************************************************************************
-
- do_open_file is used to open a file with its name in the file name
- field on the control pad. It will check whether the file name is
- typed in and ask the user to confirm if the file already exist.
-
- Output
- Return stream of opened file if the open is successful, and 0 otherwise.
-
- *****************************************************************************/
-
- FILE *do_open_file()
- {
- char *string;
- FILE *file;
-
- /* get file name in file field on control pad */
- string=(char *)panel_get_value(text_filen);
-
- /* check for empty file name */
- if ( string[0] == '\0' ) {
- do_message("Empty file name.");
- return(0);
- }
-
- /* ask user to confirm if file exist */
- if ( !(access(string, F_OK) || wmgr_confirm(basefd,"Press the left mouse button to remove file. To cancel, press the right mouse button now.")) ) {
- do_message("Cancelled.");
- return(0);
- }
-
- /* try to open the file */
- if ( !(file=fopen(string, "w+")) ) {
- do_message("Cannot open file.");
- return(0);
- }
-
- return(file);
-
- } /* do_open_file */
-
- /*****************************************************************************
-
- do_save_seg will ask the user to pick a segment to save and save
- it in the file indicated in the file field on the control pad.
-
- *****************************************************************************/
-
- do_save_seg()
- {
-
- extern int errno;
- FILE *onfile;
- int segno;
-
- /* ask the user to pick a segment */
- do_message("");
- do_usage("Select segment","","");
- if ( (segno=ge_pick()) < GE_MIN_SEG ) {
- do_usage("","","");
- do_message("No segment selected.");
- return;
- }
- do_usage("","","");
-
- /* try to open file */
- if ( !(onfile=do_open_file()) ) {
- /* abort if file cannot be openned */
- return;
- }
-
- /* write segment to file */
- ps_write_seg(onfile,segno);
-
- /* close file */
- fclose(onfile);
-
- do_message("Segment saved.");
-
- } /* do_save_seg */
-
- /*****************************************************************************
-
- do_restore will load a segment from the file indicated in the file
- field on the control pad.
-
- *****************************************************************************/
-
- do_restore_seg()
- {
-
- char *string;
- extern int errno;
- FILE *onfile;
-
- /* get file name from file field on control pad */
- string=(char *)panel_get_value(text_filen);
-
- /* try to open file */
- if (!(onfile=fopen(string, "r"))) {
- do_message("Cannot open file.");
- return;
- }
-
- /* load segment */
- if ( ! ps_load(onfile) ) {
- do_message("Segment loaded.");
- }
- else {
- do_message("File is not a saved segment.");
- }
-
- /* close file */
- fclose(onfile);
- segopen = FALSE;
-
- } /* do_restore_seg */
-
- /*****************************************************************************
-
- do_save_pic will save the picture in the file indicated in the file
- field on the control pad. It will run the optimize routine to optimize
- the display list if the optimize option is on.
-
- *****************************************************************************/
-
- do_save_pic()
- {
-
- FILE *onfile;
- extern Panel_item cycle_optm;
-
- /* try to open file in the file field */
- if ( !(onfile=do_open_file()) ) {
- return;
- }
-
- /* run the optimize routine to optimize the display list if
- the optimize option is on */
- if ( (int)panel_get_value(cycle_optm) ) {
- optimize();
- }
-
- /* save the picture */
- ps_write(onfile);
-
- /* close the file */
- fclose(onfile);
-
- do_message("Saved.");
-
- } /* do_save_pic */
-
- /*****************************************************************************
-
- do_restore_pic will load the picture from the file indicated in the
- file name field on the control pad.
-
- *****************************************************************************/
-
- do_restore_pic()
- {
-
- char *string;
- extern int errno;
- FILE *onfile;
-
- /* get the file indicated in the file field */
- string=(char *)panel_get_value(text_filen);
- if (!(onfile=fopen(string, "r"))) {
- do_message("Cannot open file.");
- return;
- }
-
- /* load picture */
- if ( ! ps_load(onfile) ) {
- do_message("Picture loaded.");
- segopen = FALSE;
- }
- else {
- do_message("File is not a saved picture.");
- }
-
- /* close file */
- fclose(onfile);
-
- } /* do_restore_pic */
-
- /*****************************************************************************
-
- do_raster will write the pixrect image of whole/part of the picture on
- the already opened onfile. It will remove the samples and grid from
- the view surface and refresh the view surface before getting the
- pixrect image.
-
- Input
- onfile - opened stream for writing
-
- *****************************************************************************/
-
- do_raster(onfile)
- FILE *onfile;
- {
- float xmin, ymin, xmax, ymax;
- int butnum,i;
- extern Panel_item cycle_raster;
-
- /* display list of samples */
- struct {
- int deleted;
- struct list *dlist;
- } samples[4];
-
- /* segments which should be invisible on the raster file */
- static int sampleseg[] = {GE_COLOR_SAMPLE,GE_LINE_SAMPLE,
- GE_CHAR_SAMPLE, GE_GRID};
-
- /* set region to dump */
- xmin=0.; ymin=0.;
- if ( (int)panel_get_value(cycle_raster) ) {
-
- /* ask for region to dump when raster option is on */
- do_usage("Reset corner","","Done");
- do {
-
- xmax=xmin;
- ymax=ymin;
- ge_locator(6, &butnum, &xmax, &ymax);
- if ( butnum == 1 ) {
- /* reset corner */
- xmin=xmax;
- ymin=ymax;
- }
-
- } while ( butnum != 3 );
- do_usage("","","");
-
- }
-
- else {
- /* dump the whole view surface */
- xmax=GE_WIN_X;
- ymax=GE_WIN_Y;
- }
-
- /* remove the samples from the view surface */
- for ( i=0; i<4; i++ ) {
- if ( (samples[i].dlist = ge_display_list(sampleseg[i])) &&
- ! (samples[i].deleted = samples[i].dlist->attr.deleted)){
- samples[i].dlist->attr.deleted = 1;
- ge_draw(sampleseg[i]);
- } /* if */
- } /* for */
-
- /* refresh the screen */
- ge_refresh();
-
- /* dump the region to onfile */
- core_write(onfile, xmin, ymin, xmax, ymax);
-
- /* redraw the samples and grid */
- for ( i=0; i<4; i++ ) {
- if ( samples[i].dlist && (!samples[i].deleted) ) {
- samples[i].dlist->attr.deleted = 0;
- ge_draw(sampleseg[i]);
- } /* if */
- } /* for */
-
- } /* do_raster */
-
- /*****************************************************************************
-
- do_output will write the picture in the format specified by the
- output format option to the file indicated in the file field on the
- control pad. It will try to open the file, and then call the
- corresponding routine to write the picture.
-
- *****************************************************************************/
-
- do_output()
- {
- extern Panel_item cycle_output;
-
- int format;
- FILE *onfile;
- FILE savestdout;
-
- do_message("");
-
- /* open the file indicated in the file field on the control pad */
- if ( !(onfile=do_open_file()) ) {
- return;
- } /* if */
-
- /* get the format from the output format option */
- format=(int)panel_get_value(cycle_output);
-
- switch ( format ) {
- case 0:
- /* raster file */
- do_raster(onfile);
- break;
-
- case 1:
- /* pic */
- pic_write(onfile);
- fclose(onfile);
- break;
- case 2:
- /* plot */
-
- /* make onfile the standard output file so that the plot library will
- write to onfile */
- savestdout = *stdout;
- *stdout = *onfile;
-
- plt_write();
-
- /* reset standard output */
- *stdout=savestdout;
- break;
-
- } /* switch */
-
- do_message("Written");
-
- } /* do_output */
-
- /*****************************************************************************
-
- do_global_scale will scale and move the whole picture within a rectangular
- region specified by the user.
-
- *****************************************************************************/
-
- do_global_scale()
- {
- float xmin, ymin, xmax, ymax;
- float tmp, sx, sy, tx, ty;
- int butnum,i;
-
- /* ask for the region to scale to */
- do_message("");
- do_usage("Reset corner","Cancel","Done");
- xmin=0.; ymin=0.;
- do {
- xmax=xmin;
- ymax=ymin;
- ge_locator(6, &butnum, &xmax, &ymax);
- if ( butnum == 1 ) {
- /* reset corner */
- xmin=xmax;
- ymin=ymax;
- }
- if ( butnum == 2 ) {
- /* cancel scale */
- do_usage("","","");
- do_message("Cancelled.");
- return;
- }
- } while ( butnum != 3 );
- do_usage("","","");
-
- /* get lower left corner in (xmin,ymin) and upper right corner in
- (xmax,ymax) */
- if ( xmin > xmax ) {
- tmp=xmin;
- xmin=xmax;
- xmax=tmp;
- }
- if ( ymin > ymax ) {
- tmp=ymin;
- ymin=ymax;
- ymax=tmp;
- }
-
- /* determine the scale and movement */
- sx = (xmax - xmin)/GE_WIN_X;
- sy = (ymax - ymin)/GE_WIN_Y;
- tx = xmin;
- ty = ymin;
-
- /* scan the segment list to scale all segments except the
- samples */
- for ( i=ge_seglist; i; i=ge_open[i].next ) {
- if ( ge_open[i].segno >= GE_MIN_SEG ) {
- float sina, cosa, nx, ny;
-
- sina=sin((double)ge_open[i].attr.ang);
- cosa=cos((double)ge_open[i].attr.ang);
-
- /* determine the new translate value, scaling at (0,0)
- in world coordinate */
- nx = (-ge_open[i].attr.tx*cosa - ge_open[i].attr.ty*sina)/
- ge_open[i].attr.sx;
- ny = (-ge_open[i].attr.ty*cosa + ge_open[i].attr.tx*sina)/
- ge_open[i].attr.sy;
- ge_open[i].attr.tx += nx*cosa*ge_open[i].attr.sx*(1-sx) -
- ny*sina*ge_open[i].attr.sy*(1-sy) + tx;
- ge_open[i].attr.ty += nx*sina*ge_open[i].attr.sx*(1-sx) +
- ny*cosa*ge_open[i].attr.sy*(1-sy) + ty;
-
- /* determine the new scale factor */
- ge_open[i].attr.sx *= sx;
- ge_open[i].attr.sy *= sy;
-
- /* redraw segment */
- ge_redisplay(&(ge_open[i]));
-
- } /* if */
-
- } /* for */
-
- } /* do_global_scale */
- @//E*O*F draw.c.shar2//
- chmod u=rw,g=r,o=r draw.c.shar2
-
- echo x - /tmp/catshar
- sed 's/^@//' > "/tmp/catshar" <<'@//E*O*F /tmp/catshar//'
- #!/bin/csh
- #
- # This script combine draw.c.shar1 and draw.c.shar2 together
- if ( -f draw.c.shar1 && -f draw.c.shar2 ) then
- echo 'Reconstruct draw.c from draw.c.shar1 and draw.c.shar2...'
- cat draw.c.shar1 draw.c.shar2 >> draw.c
- /bin/rm -f draw.c.shar1 draw.c.shar2
- endif
- exit 0
- @//E*O*F /tmp/catshar//
- chmod u=rwx,g=rx,o=rx /tmp/catshar
-
- echo Inspecting for damage in transit...
- temp=/tmp/shar$$; dtemp=/tmp/.shar$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 1013 3155 28120 draw.c.shar2
- 9 38 275 catshar
- 1022 3193 28395 total
- !!!
- wc draw.c.shar2 /tmp/catshar | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if [ -s $dtemp ]
- then echo "Ouch [diff of wc output]:" ; cat $dtemp
- else echo "No problems found."
- fi
- /tmp/catshar
- /bin/rm -f /tmp/catshar
- exit 0
-
-
-